#include "hal_data.h"
#include <stdio.h>
#include "r_sci_uart.h"
#include "coremark.h"

#define TICKS_PER_SECOND 1000

volatile uint32_t g_tick_count = 0;

void hal_systick_init()
{
    SysTick_Config(SystemCoreClock / TICKS_PER_SECOND);
}

void SysTick_Handler(void)
{
    g_tick_count += 1;
}

uint32_t hal_systick_get()
{
    return g_tick_count;
}

void hal_uart9_init()
{
    R_SCI_UART_Open(&g_uart9_ctrl, &g_uart9_cfg);
}

volatile bool hal_uart_tx_done = false;

void hal_uart9_callback(uart_callback_args_t* p_args)
{
   switch (p_args->event)
   {
   	   case UART_EVENT_RX_CHAR:
           break;
       case UART_EVENT_TX_COMPLETE:
           hal_uart_tx_done = true;
           break;
       default:
           break;
   }
}

int fputc(int ch, FILE* f)
{
    (void) f;

    hal_uart_tx_done = false;
    R_SCI_UART_Write(&g_uart9_ctrl, (uint8_t *)&ch, 1);

    while (hal_uart_tx_done == false);
    return ch;
}


FSP_CPP_HEADER
void R_BSP_WarmStart(bsp_warm_start_event_t event);
FSP_CPP_FOOTER

/*******************************************************************************************************************//**
 * main() is generated by the RA Configuration editor and is used to generate threads if an RTOS is used.  This function
 * is called by main() when no RTOS is used.
 **********************************************************************************************************************/
void hal_entry(void)
{
    /* TODO: add your own code here */
    hal_uart9_init();
    hal_systick_init();

    printf("CoreMark running on Renesas FPB-RA6E1 ...\r\n");
    printf("porting by xusiwei1236: https://bbs.elecfans.com/user/731071/\r\n");
    coremark_main();

    // while (1) {
    //     R_BSP_SoftwareDelay(1000, BSP_DELAY_UNITS_MILLISECONDS);
    //     printf("ticks: %d\r\n", hal_systick_get());
    // }

#if BSP_TZ_SECURE_BUILD
    /* Enter non-secure code */
    R_BSP_NonSecureEnter();
#endif
}

/*******************************************************************************************************************//**
 * This function is called at various points during the startup process.  This implementation uses the event that is
 * called right before main() to set up the pins.
 *
 * @param[in]  event    Where at in the start up process the code is currently at
 **********************************************************************************************************************/
void R_BSP_WarmStart (bsp_warm_start_event_t event)
{
    if (BSP_WARM_START_RESET == event)
    {
#if BSP_FEATURE_FLASH_LP_VERSION != 0

        /* Enable reading from data flash. */
        R_FACI_LP->DFLCTL = 1U;

        /* Would normally have to wait tDSTOP(6us) for data flash recovery. Placing the enable here, before clock and
         * C runtime initialization, should negate the need for a delay since the initialization will typically take more than 6us. */
#endif
    }

    if (BSP_WARM_START_POST_C == event)
    {
        /* C runtime environment and system clocks are setup. */

        /* Configure pins. */
        R_IOPORT_Open(&g_ioport_ctrl, g_ioport.p_cfg);
    }
}

#if BSP_TZ_SECURE_BUILD

BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ();

/* Trustzone Secure Projects require at least one nonsecure callable function in order to build (Remove this if it is not required to build). */
BSP_CMSE_NONSECURE_ENTRY void template_nonsecure_callable ()
{

}
#endif
